package com.easy.demo.controller;

import com.alibaba.excel.EasyExcel;
import com.basic.domain.ResultVo;
import com.deepoove.poi.XWPFTemplate;
import com.easy.annotations.RestMapping;
import com.easy.demo.entity.User;
import com.easy.demo.service.UserService;
import com.file.domain.Head;
import com.file.tool.FileTool;
import com.file.tool.web.ExcelTool;
import com.file.tool.web.WordTool;
import org.apache.commons.math3.util.Pair;
import org.springframework.web.bind.annotation.GetMapping;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 文件操作 控制器
 *
 * @author LZH
 * @version 1.0.7
 * @since 2023/06/14
 */
@RestMapping("file")
public class FileController {

    /**
     * 项目根目录
     */
    private static final String ROOT_PATH = System.getProperty("user.dir");

    @Resource
    private UserService service;

    // -------------------------- 以下为 Excel 文件导出 --------------------------

    /**
     * Excel 文件导出
     *
     * @param response {@link HttpServletResponse}
     * @return {@link ResultVo}
     */
    @GetMapping("01")
    public ResultVo<Void> export1(HttpServletResponse response) {
        // 获取数据
        List<User> list = service.getList();
        // 导出文件
        ExcelTool.export("Excel文件导出示例-01.xlsx", list, response);
        // 返回响应
        return ResultVo.ok();
    }

    /**
     * Excel 文件导出
     *
     * @param response {@link HttpServletResponse}
     * @return {@link ResultVo}
     */
    @GetMapping("02")
    public ResultVo<Void> export2(HttpServletResponse response) {
        // 获取数据
        List<User> list = service.getList();
        // 构建文件地址
        String path = ROOT_PATH + "/assets/导出Excel文件案例-1.xlsx";
        // 读取文件
        InputStream is = FileTool.readStream(path);
        // 导出文件
        ExcelTool.export("Excel文件导出示例-02.xlsx", is, list, response);
        // 返回响应
        return ResultVo.ok();
    }

    /**
     * Excel 文件导出
     *
     * @param response {@link HttpServletResponse}
     * @return {@link ResultVo}
     */
    @GetMapping("03")
    public ResultVo<Void> export3(HttpServletResponse response) {
        // 获取数据
        List<User> list = service.getList();
        // 构造额外数据
        Map<String, String> map = new HashMap<>(8);
        map.put("head", "梁山好汉 109 犟");
        map.put("time", "2099年12月31日");
        map.put("author", "施耐庵");
        map.put("num", "7");
        // 构建文件地址
        String path = ROOT_PATH + "/assets/导出Excel文件案例-2.xlsx";
        // 读取文件
        InputStream is = FileTool.readStream(path);
        // 导出文件
        ExcelTool.export("Excel文件导出示例-03.xlsx", is, list, map, true, response);
        // 返回响应
        return ResultVo.ok();
    }

    /**
     * Excel 文件导出
     *
     * @param response {@link HttpServletResponse}
     * @return {@link ResultVo}
     */
    @GetMapping("04")
    public ResultVo<Void> export4(HttpServletResponse response) {
        // 获取数据
        List<User> list = service.getList();
        // 导出文件
        ExcelTool.export("Excel文件导出示例-04.xlsx", response, out -> EasyExcel.write(out, User.class).sheet().doWrite(list));
        // 返回响应
        return ResultVo.ok();
    }

    // -------------------------- 以下为 Excel 文件解析 --------------------------

    /**
     * 解析 Excel 文件内容
     *
     * @return {@link ResultVo}
     */
    @GetMapping("11")
    public ResultVo<Void> parse1() {
        // 构建文件地址
        String path = ROOT_PATH + "/assets/解析Excel文件案例-1.xlsx";
        // 读取文件
        InputStream is = FileTool.readStream(path);
        // 解析文件
        ExcelTool.parse(is, User.class).forEach(System.out::println);
        // 返回响应
        return ResultVo.ok();
    }

    /**
     * 解析 Excel 文件内容
     *
     * @return {@link ResultVo}
     */
    @GetMapping("12")
    public ResultVo<Void> parse2() {
        // 构建文件地址
        String path = ROOT_PATH + "/assets/解析Excel文件案例-1.xlsx";
        // 读取文件
        InputStream is = FileTool.readStream(path);
        // 解析文件
        ExcelTool.parse(is, User.class, list -> list.forEach(System.out::println));
        // 返回响应
        return ResultVo.ok();
    }

    /**
     * 解析 Excel 文件内容
     *
     * @return {@link ResultVo}
     */
    @GetMapping("13")
    public ResultVo<Void> parse3() {
        // 构建文件地址
        String path = ROOT_PATH + "/assets/解析Excel文件案例-1.xlsx";
        // 读取文件
        InputStream is = FileTool.readStream(path);
        // 解析文件
        ExcelTool.parse(is, User.class, 2, list -> {
            System.out.println("====== 模拟数据过多的大文件, 分批次读取文件内容 ======");
            list.forEach(System.out::println);
        });
        // 返回响应
        return ResultVo.ok();
    }

    /**
     * 解析 Excel 文件内容
     *
     * @return {@link ResultVo}
     */
    @GetMapping("14")
    public ResultVo<Void> parse4() {
        // 构建文件地址
        String path = ROOT_PATH + "/assets/解析Excel文件案例-2.xlsx";
        // 读取文件
        InputStream is = FileTool.readStream(path);
        // 解析文件
        Pair<List<User>, List<Head<?>>> list = ExcelTool.parse(is, User.class, 5);
        // 表格数据
        list.getKey().forEach(System.out::println);
        System.out.println("-------------------------------------------------------------");
        // 表头数据
        list.getValue().forEach(t -> System.out.printf("行: %s, 列: %s, 文本: %s%n", t.getRow(), t.getCol(), t.getVal()));
        // 返回响应
        return ResultVo.ok();
    }

    // -------------------------- 以下为 Word 文件导出 --------------------------

    /**
     * word 文件导出
     *
     * @param response {@link HttpServletResponse}
     * @return {@link ResultVo}
     */
    @GetMapping("21")
    public ResultVo<Void> export11(HttpServletResponse response) {
        // 构建文件地址
        String path = ROOT_PATH + "/assets/导出Word文件案例-1.docx";
        // 读取文件
        InputStream is = FileTool.readStream(path);
        // 构建数据
        Map<String, Object> form = new HashMap<>(4);
        form.put("title", "水浒传");
        form.put("name", "宋江");
        // 填充文件并导出
        WordTool.export("导出Word文件案例-01.docx", is, form, response);
        // 返回响应
        return ResultVo.ok();
    }

    /**
     * word 文件导出
     *
     * @param response {@link HttpServletResponse}
     * @return {@link ResultVo}
     */
    @GetMapping("22")
    public ResultVo<Void> export12(HttpServletResponse response) {
        // 构建文件地址
        String path = ROOT_PATH + "/assets/导出Word文件案例-2.docx";
        // 读取文件
        InputStream is = FileTool.readStream(path);
        // 构建表格
        Map<String, Object> form = new HashMap<>(4);
        form.put("title", "水浒传");
        form.put("name", "宋江");
        // 构建列表
        Map<String, List<User>> table = new HashMap<>(2);
        table.put("user", service.getList());
        // 填充文件并导出
        WordTool.export("导出Word文件案例-02.docx", is, form, table, response);
        // 返回响应
        return ResultVo.ok();
    }

    /**
     * word 文件导出
     *
     * @param response {@link HttpServletResponse}
     * @return {@link ResultVo}
     */
    @GetMapping("23")
    public ResultVo<Void> export13(HttpServletResponse response) {
        // 构建文件地址
        String wordPath = ROOT_PATH + "/assets/导出Word文件案例-3.docx";
        // 构建图片地址
        // noinspection DuplicatedCode
        String picturePath = ROOT_PATH + "/assets/导出带图片的word文件案例.png";
        // 读取 word 文件
        InputStream word = FileTool.readStream(wordPath);
        // 读取图片文件
        byte[] bytes = FileTool.readBytes(picturePath);
        // 构建表格
        Map<String, Object> form = new HashMap<>(4);
        form.put("title", "水浒传");
        form.put("name", "宋江");
        // 构建图片
        Map<String, byte[]> picture = new HashMap<>(2);
        picture.put("picture", bytes);
        // 填充文件并导出
        WordTool.export("导出Word文件案例-03.docx", word, form, response, picture);
        // 返回响应
        return ResultVo.ok();
    }

    /**
     * word 文件导出
     *
     * @param response {@link HttpServletResponse}
     * @return {@link ResultVo}
     */
    @GetMapping("24")
    public ResultVo<Void> export14(HttpServletResponse response) {
        // 构建文件地址
        String wordPath = ROOT_PATH + "/assets/导出Word文件案例-4.docx";
        // 构建图片地址
        // noinspection DuplicatedCode
        String picturePath = ROOT_PATH + "/assets/导出带图片的word文件案例.png";
        // 读取 word 文件
        InputStream word = FileTool.readStream(wordPath);
        // 读取图片文件
        byte[] bytes = FileTool.readBytes(picturePath);
        // 构建表格
        Map<String, Object> form = new HashMap<>(4);
        form.put("title", "水浒传");
        form.put("name", "宋江");
        // 构建图片
        Map<String, byte[]> picture = new HashMap<>(2);
        picture.put("picture", bytes);
        // 构建列表
        Map<String, List<User>> table = new HashMap<>(2);
        table.put("user", service.getList());
        // 填充文件并导出
        WordTool.export("导出Word文件案例-04.docx", word, form, table, picture, response);
        // 返回响应
        return ResultVo.ok();
    }

    /**
     * word 文件导出
     *
     * @param response {@link HttpServletResponse}
     * @return {@link ResultVo}
     */
    @GetMapping("25")
    public ResultVo<Void> export15(HttpServletResponse response) {
        // 构建文件地址
        String path = ROOT_PATH + "/assets/导出Word文件案例-1.docx";
        // 读取文件
        InputStream is = FileTool.readStream(path);
        // 构建数据
        Map<String, Object> form = new HashMap<>(4);
        form.put("title", "水浒传");
        form.put("name", "宋江");
        // 填充文件并导出
        WordTool.export("导出Word文件案例-05.docx", response, os -> {
            try {
                XWPFTemplate.compile(is).render(form).write(os);
            } catch (IOException e) {
                // catch...
            }
        });
        // 返回响应
        return ResultVo.ok();
    }
}
